﻿using Microsoft.Xna.Framework;
using System;
using Terraria;
using Terraria.Audio;
using Terraria.ID;
using Terraria.ModLoader;

namespace MoLingsArmory.Content.Projectiles
{
    public class NebularStaffHold : ModProjectile
    {
        public override string Texture { get { return "Terraria/Images/Projectile_" + ProjectileID.PulseBolt; } }
        public float MoveDistance = 88;
        public float Distance
        {
            get { return Projectile.ai[0]; }
            set { Projectile.ai[0] = value; }
        }
        public override void SetDefaults()
        {
            Projectile.alpha = 255;
            Projectile.width = 4;
            Projectile.height = 4;
            Projectile.friendly = false;
            Projectile.penetrate = -1;
            Projectile.tileCollide = false;
            Projectile.DamageType = DamageClass.Magic;
        }
        public override bool PreDraw(ref Color lightColor)
        {
            return false;
        }
        public float chargeLv;
        public bool shotFinished = false;
        public bool canNotifyFull = true;
        public bool forceFire = false;
        public float damageMult = 1f;
        public float projectileCount = 3;
        public int finishCounter;
        public int soundCounter = 0;
        public override void AI()
        {
            Vector2 mousePos = Main.MouseWorld;
            Player player = Main.player[Projectile.owner];
            if (Projectile.owner == Main.myPlayer)
            {
                Vector2 diff = mousePos - player.Center;
                diff.Normalize();
                Projectile.velocity = diff;
                Projectile.direction = Main.MouseWorld.X > player.position.X ? 1 : -1;
                Projectile.netUpdate = true;
            }
            Projectile.position = player.itemLocation + Projectile.velocity * MoveDistance;
            Projectile.timeLeft = 2;
            int dir = Projectile.direction;
            player.ChangeDir(dir);
            player.heldProj = Projectile.whoAmI;
            player.itemTime = 2;
            player.itemAnimation = 2;
            Vector2 dustPos = player.Center + Projectile.velocity * Distance;
            if (player.channel)
            {
                player.itemRotation = (float)Math.Atan2(Projectile.velocity.Y * dir, Projectile.velocity.X * dir);
            }
            if (chargeLv == 30)
            {
                SoundEngine.PlaySound(SoundID.Item13, player.position);
            }
            if (chargeLv > 35)
            {
                soundCounter++;
                if (soundCounter > 15)
                {
                    soundCounter = 0;
                    SoundEngine.PlaySound(SoundID.Item15, player.position);
                }
            }
            if (chargeLv < 180 && player.channel)
            {
                chargeLv++;
                if (chargeLv > 30)
                {
                    if (Main.time % 12 < 1 && !player.CheckMana(4, true))
                    {
                        forceFire = true;
                    }
                    Vector2 offset = Projectile.velocity;
                    offset *= MoveDistance - 20;
                    Vector2 pos = player.Center + offset - new Vector2(10, 10);

                    float chargeFact = chargeLv / 20f;
                    Vector2 dustVelocity = Vector2.UnitX * 18f;
                    dustVelocity = dustVelocity.RotatedBy(Projectile.rotation - 1.57f, default);
                    Vector2 spawnPos = Projectile.Center + dustVelocity;
                    for (int k = 0; k < chargeFact + 1; k++)
                    {
                        Vector2 spawn = spawnPos + ((float)Main.rand.NextDouble() * 6.28f).ToRotationVector2() * (12f - chargeFact * 2);
                        Dust dust = Main.dust[Dust.NewDust(pos, 20, 20, DustID.PinkTorch, Projectile.velocity.X / 2f, Projectile.velocity.Y / 2f, 0, default, 1f)];
                        dust.velocity = Vector2.Normalize(spawnPos - spawn) * 3f * (chargeFact * 2f) / 10f;
                        dust.noGravity = true;
                        dust.scale = Main.rand.Next(10, 20) * 0.05f;
                    }
                }
            }
            else if (chargeLv >= 180 && player.channel && canNotifyFull)
            {
                Vector2 offset = Projectile.velocity;
                offset *= MoveDistance - 20;
                Vector2 pos = player.Center + offset - new Vector2(10, 10);
                Vector2 dustVelocity = Vector2.UnitX * 18f;
                dustVelocity = dustVelocity.RotatedBy(Projectile.rotation - 1.57f, default);
                Vector2 spawnPos = Projectile.Center + dustVelocity;
                canNotifyFull = false;
                SoundEngine.PlaySound(SoundID.MaxMana, player.position);
                for (int i = 0; i < 10; i++)
                {
                    Vector2 spawn = spawnPos + ((float)Main.rand.NextDouble() * 6.28f).ToRotationVector2() * 12f;
                    int num274 = Dust.NewDust(pos, 20, 20, DustID.CrystalPulse2, 0f, 0f, 100, default, 2.5f);
                    Dust dust = Main.dust[num274];
                    dust.velocity = Vector2.Normalize(spawnPos - spawn) * 8f;
                    dust.noGravity = true;
                }
            }
            else if (chargeLv >= 180 && player.channel)
            {
                Vector2 offset = Projectile.velocity;
                offset *= MoveDistance - 20;
                Vector2 pos = player.Center + offset - new Vector2(10, 10);

                Vector2 dustVelocity = Vector2.UnitX * 18f;
                dustVelocity = dustVelocity.RotatedBy(Projectile.rotation - 1.57f, default);
                Vector2 spawnPos = Projectile.Center + dustVelocity;
                for (int k = 0; k < 2 + 1; k++)
                {
                    Vector2 spawn = spawnPos + ((float)Main.rand.NextDouble() * 6.28f).ToRotationVector2() * 12f;
                    Dust dust = Main.dust[Dust.NewDust(pos, 20, 20, DustID.PinkTorch, Projectile.velocity.X / 2f,
                        Projectile.velocity.Y / 2f, 0, default, 1f)];
                    dust.velocity = Vector2.Normalize(spawnPos - spawn) * 6.5f;
                    dust.noGravity = true;
                    dust.scale = Main.rand.Next(10, 20) * 0.075f;
                }
            }
            if (chargeLv < 80)
            {
                projectileCount = 3;
            }
            else if (chargeLv < 130)
            {
                projectileCount = 4;
            }
            else if (chargeLv < 180)
            {
                projectileCount = 5;
            }
            if (chargeLv > 30 && chargeLv < 180)
            {
                damageMult = 1f + (float)(chargeLv * 0.006666667);
            }
            else if (chargeLv == 180)
            {
                damageMult = 2.5f;
            }
            if (chargeLv < 30 && !shotFinished && (!player.channel || forceFire))
            {
                shotFinished = true;
                if (Main.myPlayer == Projectile.owner)
                {
                    Projectile.NewProjectile(Projectile.GetSource_FromAI(), player.Center.X, player.Center.Y, Projectile.velocity.X * 12f, Projectile.velocity.Y * 12f, ModContent.ProjectileType<NebulaNova>(), Projectile.damage, Projectile.knockBack, player.whoAmI, 0f, 2f);
                }
                SoundEngine.PlaySound(SoundID.DD2_FlameburstTowerShot, Projectile.position);
            }
            else if (chargeLv < 180 && !shotFinished && (!player.channel || forceFire))
            {
                shotFinished = true;
                float rotation = MathHelper.ToRadians(6);
                SoundEngine.PlaySound(SoundID.DD2_FlameburstTowerShot, Projectile.position);
                Vector2 shotPos = player.Center + Vector2.Normalize(new Vector2(Projectile.velocity.X, Projectile.velocity.Y)) * 8f;
                for (int currProj = 0; currProj < projectileCount; currProj++)
                {
                    Vector2 perturbedSpeed = new Vector2(Projectile.velocity.X * (20f * projectileCount), Projectile.velocity.Y * (20f * projectileCount)).RotatedBy(MathHelper.Lerp(-rotation, rotation, currProj / (projectileCount - 1))) * .2f; // Watch out for dividing by 0 if there is only 1 projectile.
                    if (Main.myPlayer == Projectile.owner)
                    {
                        Projectile.NewProjectile(Projectile.GetSource_FromAI(), shotPos.X, shotPos.Y, perturbedSpeed.X, perturbedSpeed.Y, ModContent.ProjectileType<NebulaNova>(), (int)(Projectile.damage * damageMult), Projectile.knockBack, player.whoAmI, 0f, 2f);
                    }
                }
            }
            else if (chargeLv >= 180 && !shotFinished && (!player.channel || forceFire))
            {
                shotFinished = true;
                float rotation = MathHelper.ToRadians(5);
                Vector2 shotPos = player.Center + Vector2.Normalize(new Vector2(Projectile.velocity.X, Projectile.velocity.Y)) * 8f;
                SoundEngine.PlaySound(SoundID.DD2_FlameburstTowerShot, Projectile.position);
                SoundEngine.PlaySound(SoundID.Item74, Projectile.position);
                for (int currProj = 0; currProj < projectileCount; currProj++)
                {
                    Vector2 perturbedSpeed = new Vector2(Projectile.velocity.X * (21f * projectileCount), Projectile.velocity.Y * (21f * projectileCount)).RotatedBy(MathHelper.Lerp(-rotation, rotation, currProj / (projectileCount - 1))) * .2f; // Watch out for dividing by 0 if there is only 1 projectile.
                    if (Main.myPlayer == Projectile.owner)
                    {
                        int proj = Projectile.NewProjectile(Projectile.GetSource_FromAI(), shotPos.X, shotPos.Y, perturbedSpeed.X, perturbedSpeed.Y, ModContent.ProjectileType<NebulaNova>(), (int)(Projectile.damage * damageMult), Projectile.knockBack, player.whoAmI, 0f, 2f);
                        Main.projectile[proj].ai[1] = 1;
                    }
                }
            }
            if (shotFinished)
            {
                finishCounter++;

                if (finishCounter >= 19)
                {
                    Projectile.Kill();
                }
            }
        }
        public override bool ShouldUpdatePosition()
        {
            return false;
        }
    }
}
